﻿#include "StdAfx.h"
#include "ServiceUnits.h"
#include "ControlPacket.h"
#include "AttemperEngineSink.h"
#include "LogonServerDlg.h"
#include "json.h" 

//afternoon kiss

#define MAX_CREATE  5
//////////////////////////////////////////////////////////////////////////////////
//时间标识
#define IDI_LOAD_GAME_LIST				1									//加载列表
#define IDI_CONNECT_CORRESPOND			2									//重连标识
#define IDI_COLLECT_ONLINE_INFO		3									//统计在线

//时间定义
#define	TIME_VALID_VERIFY_CODE		0									//请求间隔


//////////////////////////////////////////////////////////////////////////////////

char* CreateUTF8TextInitWithString(CString strValue)
{
	char *buffer = NULL;
	int  length;

#ifdef _UNICODE  
	length = WideCharToMultiByte(CP_UTF8, 0, strValue, -1, NULL, 0, NULL, NULL);
#else  
	return NULL;
#endif  
	if (length <= 0)
	{
		return NULL;
	}

	buffer = new char[length];
	if (buffer == NULL)
	{
		return NULL;
	}

	ZeroMemory(buffer, length);

#ifdef _UNICODE  
	WideCharToMultiByte(CP_UTF8, 0, strValue, -1, buffer, length, NULL, NULL);
#else  
	strcpy_s(buffer, length, strValue);
#endif  

	return buffer;
}

TCHAR* Char2WChar(std::string pwszSrc)
{
	USES_CONVERSION;
	TCHAR * cLineChar = A2W(pwszSrc.c_str());
	return cLineChar;
}

//构造函数
CAttemperEngineSink::CAttemperEngineSink()
{
	//状态变量
	m_bNeekCorrespond = true;
	m_bShowServerStatus = false;
	m_KindID = 0;
	//状态变量
	m_pInitParameter = NULL;

	//组件变量
	m_pITimerEngine = NULL;
	m_pIDataBaseEngine = NULL;
	m_pITCPNetworkEngine = NULL;
	m_pITCPSocketService = NULL;

	return;
}

//析构函数
CAttemperEngineSink::~CAttemperEngineSink()
{
}

//接口查询
VOID * CAttemperEngineSink::QueryInterface(REFGUID Guid, DWORD dwQueryVer)
{
	QUERYINTERFACE(IAttemperEngineSink, Guid, dwQueryVer);
	QUERYINTERFACE_IUNKNOWNEX(IAttemperEngineSink, Guid, dwQueryVer);
	return NULL;
}

//启动事件
bool CAttemperEngineSink::OnAttemperEngineStart(IUnknownEx * pIUnknownEx)
{

	//设置时间
	ASSERT(m_pITimerEngine != NULL);

	CLogonServerDlg*pDlg = (CLogonServerDlg*)(AfxGetApp()->GetMainWnd());
	if (pDlg->m_ServiceUnits.m_KindID == 0)
	{
		CTraceService::TraceString(_T("登陆启动失败，请使用命令行重新启动 格式:start LogonServer.exe /ServerID:8600 /KindID:103"), TraceLevel_Exception);
		return false;
	}
	else
	{
		m_KindID = pDlg->m_ServiceUnits.m_KindID;
	}

	if (m_WhRedisServer.InitRedisServer() == false)
	{
		ASSERT(FALSE);
		CTraceService::TraceString(_T("redis连接失败"), TraceLevel_Exception);
		return false;
	}

	//登陆系统日志
	CServerPushLog::SharedLog()->SetSocketUserID(_T("好友服务器"), SYSFRIENDLOG);
	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("好友服务器启动成功"));
	//检查群ID
	CheckCreateGroupID();

	GetRedisToRoomList();
	return true;
}

//停止事件
bool CAttemperEngineSink::OnAttemperEngineConclude(IUnknownEx * pIUnknownEx)
{
	//状态变量
	m_bNeekCorrespond = true;

	//组件变量
	m_pITimerEngine = NULL;
	m_pIDataBaseEngine = NULL;
	m_pITCPNetworkEngine = NULL;
	m_pITCPSocketService = NULL;

	return true;
}


//时间事件
bool CAttemperEngineSink::OnEventTimer(DWORD dwTimerID, WPARAM wBindParam)
{
	if (dwTimerID == IDI_CONNECT_CORRESPOND)	//连接协调
	{
		//发起连接
		tagAddressInfo * pCorrespondAddress = &m_pInitParameter->m_CorrespondAddress;
		m_pITCPSocketService->Connect(pCorrespondAddress->szAddress, m_pInitParameter->m_wCorrespondPort);

		//构造提示
		TCHAR szString[512] = TEXT("");
		_sntprintf(szString, CountArray(szString), TEXT("正在连接协调服务器 [ %s:%d ]"), pCorrespondAddress->szAddress, m_pInitParameter->m_wCorrespondPort);

		//提示消息
		CTraceService::TraceString(szString, TraceLevel_Normal);

		return true;
	}

	return false;
}

//关闭事件
bool CAttemperEngineSink::OnEventTCPSocketShut(WORD wServiceID, BYTE cbShutReason)
{
	//协调连接
	if (wServiceID == NETWORK_CORRESPOND)
	{
		//重连判断
		if (m_bNeekCorrespond == true)
		{
			//构造提示
			TCHAR szDescribe[128] = TEXT("");
			_sntprintf(szDescribe, CountArray(szDescribe), TEXT("与协调服务器的连接关闭了，%ld 秒后将重新连接"), m_pInitParameter->m_wConnectTime);

			//提示消息
			CTraceService::TraceString(szDescribe, TraceLevel_Warning);

			//设置时间
			ASSERT(m_pITimerEngine != NULL);
			m_pITimerEngine->SetTimer(IDI_CONNECT_CORRESPOND, m_pInitParameter->m_wConnectTime * 1000L, 1, 0);

			return true;
		}
	}

	return false;
}

//连接事件
bool CAttemperEngineSink::OnEventTCPSocketLink(WORD wServiceID, INT nErrorCode)
{
	//协调连接
	if (wServiceID == NETWORK_CORRESPOND)
	{
		//错误判断
		if (nErrorCode != 0)
		{
			//构造提示
			TCHAR szDescribe[128] = TEXT("");
			_sntprintf(szDescribe, CountArray(szDescribe), TEXT("协调服务器连接失败 [ %ld ]，%ld 秒后将重新连接"),
				nErrorCode, m_pInitParameter->m_wConnectTime);

			//提示消息
			CTraceService::TraceString(szDescribe, TraceLevel_Warning);

			//设置时间
			ASSERT(m_pITimerEngine != NULL);
			m_pITimerEngine->SetTimer(IDI_CONNECT_CORRESPOND, m_pInitParameter->m_wConnectTime * 1000L, 1, 0);

			return false;
		}


		//提示消息
		CTraceService::TraceString(TEXT("正在注册游戏登录服务器..."), TraceLevel_Normal);

		//变量定义
		CMD_CS_C_RegisterPlaza RegisterPlaza;
		ZeroMemory(&RegisterPlaza, sizeof(RegisterPlaza));

		//设置变量
		lstrcpyn(RegisterPlaza.szServerName, m_pInitParameter->m_szServerName, CountArray(RegisterPlaza.szServerName));
		lstrcpyn(RegisterPlaza.szServerAddr, m_pInitParameter->m_ServiceAddress.szAddress, CountArray(RegisterPlaza.szServerAddr));

		//发送数据
		m_pITCPSocketService->SendData(MDM_CS_REGISTER, SUB_CS_C_REGISTER_GROUP, &RegisterPlaza, sizeof(RegisterPlaza));

		return true;
	}

	return true;
}

//读取事件
bool CAttemperEngineSink::OnEventTCPSocketRead(WORD wServiceID, TCP_Command Command, VOID * pData, WORD wDataSize)
{
	//协调连接
	if (wServiceID == NETWORK_CORRESPOND)
	{
		switch (Command.wMainCmdID)
		{
			case MDM_CS_SERVICE_INFO:	//服务信息
				{
					return OnTCPSocketMainServiceInfo(Command.wSubCmdID, pData, wDataSize);
				}
			case MDM_CS_REGISTER:		//注册服务
				{
					return OnTCPSocketMainRegister(Command.wSubCmdID, pData, wDataSize);
				}
			case MDM_CS_REMOTE_SERVICE:
				{
					if (Command.wSubCmdID == SUB_CS_S_GROUPPLAYRESULT)  //解散群申请
					{
						DeleteGroupToServerResult(pData, wDataSize, 0);
						return true;
					}
				}
		}
	}

	return true;
}


//应答事件
bool CAttemperEngineSink::OnEventTCPNetworkBind(DWORD dwClientAddr, DWORD dwSocketID)
{
	//获取索引
	ASSERT(LOWORD(dwSocketID) < m_pInitParameter->m_wMaxConnect);
	if (LOWORD(dwSocketID) >= m_pInitParameter->m_wMaxConnect) return false;

	return true;
}

//绑定参数
tagBindParameter*  CAttemperEngineSink::GetBindParameterToUser(DWORD dwUserID)
{
	tagBindParameter TempBindParameter;
	ZeroMemory(&TempBindParameter, sizeof(TempBindParameter));
	CGroupMap::iterator  iter;
	iter = m_pBindParameterMap.find(dwUserID);
	if (iter == m_pBindParameterMap.end())
	{
		return NULL;
	}
	else
	{
		return &(iter->second);
	}
}

//添加用户参数
bool CAttemperEngineSink::AddBindParameter(CMD_GP_REGISTERUSER * pRegisterUser, DWORD dwContextID,BYTE SocketType)
{
	CGroupMap::iterator  iter;
	iter = m_pBindParameterMap.find(pRegisterUser->dwUserID);
	if (iter != m_pBindParameterMap.end())
	{
		CTraceService::TraceString(_T("用户已经进入在线管理"), TraceLevel_Exception);
		return false;
	}

	tagBindParameter  pBindParameter;
	ZeroMemory(&pBindParameter, sizeof(pBindParameter));
	pBindParameter.dwSocketType = SocketType;
	pBindParameter.dwSocketID = dwContextID;
	pBindParameter.pUserInfo.dwUserID = pRegisterUser->dwUserID;

	if (pRegisterUser->dwGameID != 0)
	{
		pBindParameter.pUserInfo.dwGameID = pRegisterUser->dwGameID;
		pBindParameter.pUserInfo.dwGropuID = 0;
		lstrcpyn(pBindParameter.pUserInfo.szNickName, pRegisterUser->szNickName, CountArray(pRegisterUser->szNickName));
		lstrcpyn(pBindParameter.pUserInfo.szWxHeadUrl, pRegisterUser->szWxHeadurl, CountArray(pRegisterUser->szWxHeadurl));
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("用户UserID:%d 昵称:%s 进入注册"), pRegisterUser->dwUserID, pRegisterUser->szNickName);
	}
	else
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("服务器 UserID:%d 进入注册"), pRegisterUser->dwUserID);
	}
	
	m_pBindParameterMap.insert(CGroupMap::value_type(pRegisterUser->dwUserID, pBindParameter));
	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("当前服务器连接人数:%d"),m_pBindParameterMap.size());

	return true;
}

//删除在线用户
bool CAttemperEngineSink::DeleteBindParameter(DWORD dwContextID)
{
	CGroupMap::iterator  iter;
	for (iter = m_pBindParameterMap.begin(); iter != m_pBindParameterMap.end(); iter++)
	{
		if (iter->second.dwSocketID == dwContextID)
		{
			CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("用户UserID:%d 昵称:%s 反注册"), iter->second.pUserInfo.dwUserID, iter->second.pUserInfo.szNickName);
			m_pBindParameterMap.erase(iter);
			return true;
		}
	}

	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("删除用户失败:%d"), m_pBindParameterMap.size());
	CTraceService::TraceString(_T("删除用户失败"), TraceLevel_Exception);

	return false;
}

//关闭事件
bool CAttemperEngineSink::OnEventTCPNetworkShut(DWORD dwClientAddr, DWORD dwActiveTime, DWORD dwSocketID)
{
	//清除信息
	DeleteBindParameter(dwSocketID);
	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("网络关闭 删除在线用户"));
	return false;
}

//发送请求
bool CAttemperEngineSink::SendUIControlPacket(WORD wRequestID, VOID * pData, WORD wDataSize)
{
	//发送数据
	CServiceUnits * pServiceUnits = CServiceUnits::g_pServiceUnits;
	pServiceUnits->PostControlRequest(wRequestID, pData, wDataSize);

	return true;
}

bool CAttemperEngineSink::DeleteGroupToServerResult(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_CS_C_GROUPLAYRESULT));
	if (wDataSize != sizeof(CMD_CS_C_GROUPLAYRESULT)) return false;

	//变量定义
	CMD_CS_C_GROUPLAYRESULT * pServerOnLine = (CMD_CS_C_GROUPLAYRESULT *)pData;

	  
	 std::map<DWORD, std::vector<bool>>::iterator  iter;
	 iter = m_DeleteGroupCntMap.find(pServerOnLine->dwGroupID);
	 if (iter == m_DeleteGroupCntMap.end())
	 {
		 std::vector<bool> mListRetult;
		 mListRetult.push_back(pServerOnLine->bIsFindResult);
		 m_DeleteGroupCntMap[pServerOnLine->dwGroupID] = mListRetult;
	 }
	 else
	 {
		 iter->second.push_back(pServerOnLine->bIsFindResult);
	 }

	 iter = m_DeleteGroupCntMap.find(pServerOnLine->dwGroupID);
	 if (m_ServerListManager.GetGameServerCount() != iter->second.size())
	 {
		 return true;
	 }

	 std::vector<bool>::iterator result = std::find(iter->second.begin(), iter->second.end(), true);
	 if (result != iter->second.end())
	 {
		 OnSendPublicMessage(dwSocketID, 200, _T("群成员正在游戏中不能删除该群!"));
		 return true;
	 }

	 /*if (pServerOnLine->bIsFindResult == true)
	 {
		 OnSendPublicMessage(dwSocketID, 200, _T("群成员正在游戏中不能删除该群!"));
		 return true;
	 }*/

	//删除群-->ID关系
	//写群号对应群主关系 (1-1)
	char RedisCmdLine[200];
	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	m_WhRedisServer.DeleteZremValule(RedisCmdLine, pServerOnLine->dwGroupID);

	//删除群主离线消息
	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPOWNEROFFLINEMESG, m_KindID, pServerOnLine->dwUserID);
	m_WhRedisServer.DeleteZremrangebylex(RedisCmdLine, pServerOnLine->dwGroupID, pServerOnLine->dwGroupID + 1);

	//刪除群成員
	DeleteOnlyGroup(pServerOnLine->dwGroupID, pServerOnLine->dwUserID, pServerOnLine->dwScoketID);

	TCHAR szDesc[128];
	_sntprintf(szDesc, CountArray(szDesc), TEXT("用户:[%d]删除亲友团[%d]"), pServerOnLine->dwUserID, pServerOnLine->dwGroupID);
	RecordGroupLog(pServerOnLine->dwGroupID, pServerOnLine->dwUserID, szDesc);
	
	//CMD_GP_OPERATIONDESC OperationDesc;
	//ZeroMemory(&OperationDesc, sizeof(OperationDesc));
	//_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已成功解散[%d]群"),pServerOnLine->dwGroupID);
	////给群主发确认操作
	//m_pITCPNetworkEngine->SendData(pServerOnLine->dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));

	return true;
}

//注册事件
bool CAttemperEngineSink::OnTCPSocketMainRegister(WORD wSubCmdID, VOID * pData, WORD wDataSize)
{
	switch (wSubCmdID)
	{
		case SUB_CS_S_REGISTER_FAILURE:		//注册失败
			{
				//变量定义
				CMD_CS_S_RegisterFailure * pRegisterFailure = (CMD_CS_S_RegisterFailure *)pData;

				//效验参数
				ASSERT(wDataSize >= (sizeof(CMD_CS_S_RegisterFailure) - sizeof(pRegisterFailure->szDescribeString)));
				if (wDataSize < (sizeof(CMD_CS_S_RegisterFailure) - sizeof(pRegisterFailure->szDescribeString))) return false;

				//关闭处理
				m_bNeekCorrespond = false;
				m_pITCPSocketService->CloseSocket();

				//显示消息
				LPCTSTR pszDescribeString = pRegisterFailure->szDescribeString;
				if (lstrlen(pszDescribeString) > 0) CTraceService::TraceString(pszDescribeString, TraceLevel_Exception);

				//事件通知
				CP_ControlResult ControlResult;
				ControlResult.cbSuccess = ER_FAILURE;
				SendUIControlPacket(UI_CORRESPOND_RESULT, &ControlResult, sizeof(ControlResult));

				return true;
			}
	}

	return true;
}

//列表事件
bool CAttemperEngineSink::OnTCPSocketMainServiceInfo(WORD wSubCmdID, VOID * pData, WORD wDataSize)
{
	switch (wSubCmdID)
	{
		case SUB_CS_S_SERVER_ONLINE:	//房间人数
			{
				//效验参数
				ASSERT(wDataSize == sizeof(CMD_CS_S_ServerOnLine));
				if (wDataSize != sizeof(CMD_CS_S_ServerOnLine)) return false;

				//变量定义
				CMD_CS_S_ServerOnLine * pServerOnLine = (CMD_CS_S_ServerOnLine *)pData;

				//查找房间
				CGameServerItem * pGameServerItem = m_ServerListManager.SearchGameServer(pServerOnLine->wServerID);
				if (pGameServerItem == NULL) return true;

				//获取对象
				tagGameServer * pGameServer = &pGameServerItem->m_GameServer;

				//设置人数
				DWORD dwOldOnlineCount = 0, dwOldAndroidCount = 0;
				dwOldOnlineCount = pGameServer->dwOnLineCount;
				dwOldAndroidCount = pGameServer->dwAndroidCount;

				//房间人数
				pGameServer->dwAndroidCount = pServerOnLine->dwAndroidCount;
				pGameServer->dwOnLineCount = pServerOnLine->dwOnLineCount;

				//目录人数
				CGameKindItem * pGameKindItem = m_ServerListManager.SearchGameKind(pGameServer->wKindID);
				if (pGameKindItem != NULL)
				{
					//目录总数
					pGameKindItem->m_GameKind.dwOnLineCount -= dwOldOnlineCount;
					pGameKindItem->m_GameKind.dwOnLineCount += pGameServer->dwOnLineCount;
				}

				return true;
			}
		case SUB_CS_S_SERVER_INSERT:	//房间插入
			{
				//效验参数
				ASSERT(wDataSize % sizeof(tagGameServer) == 0);
				if (wDataSize % sizeof(tagGameServer) != 0) return false;

				//变量定义
				WORD wItemCount = wDataSize / sizeof(tagGameServer);
				tagGameServer * pGameServer = (tagGameServer *)pData;

				//更新数据
				for (WORD i = 0; i < wItemCount; i++)
				{
					m_ServerListManager.InsertGameServer(pGameServer++);
				}

				return true;
			}
		case SUB_CS_S_SERVER_MODIFY:	//房间修改
			{
				//效验参数
				ASSERT(wDataSize == sizeof(CMD_CS_S_ServerModify));
				if (wDataSize != sizeof(CMD_CS_S_ServerModify)) return false;

				//变量定义
				CMD_CS_S_ServerModify * pServerModify = (CMD_CS_S_ServerModify *)pData;

				//查找房间
				ASSERT(m_ServerListManager.SearchGameServer(pServerModify->wServerID));
				CGameServerItem * pGameServerItem = m_ServerListManager.SearchGameServer(pServerModify->wServerID);

				//设置房间
				if (pGameServerItem != NULL)
				{
					//设置人数
					DWORD dwOldOnlineCount = 0, dwOldAndroidCount = 0, dwOldFullCount = 0;
					dwOldAndroidCount = pGameServerItem->m_GameServer.dwAndroidCount;
					dwOldOnlineCount = pGameServerItem->m_GameServer.dwOnLineCount;
					dwOldFullCount = pGameServerItem->m_GameServer.dwFullCount;

					//修改房间信息
					pGameServerItem->m_GameServer.wKindID = pServerModify->wKindID;
					pGameServerItem->m_GameServer.wNodeID = pServerModify->wNodeID;
					pGameServerItem->m_GameServer.wSortID = pServerModify->wSortID;
					pGameServerItem->m_GameServer.wServerPort = pServerModify->wServerPort;
					pGameServerItem->m_GameServer.dwOnLineCount = pServerModify->dwOnLineCount;
					pGameServerItem->m_GameServer.dwFullCount = pServerModify->dwFullCount;
					pGameServerItem->m_GameServer.dwAndroidCount = pServerModify->dwAndroidCount;
					lstrcpyn(pGameServerItem->m_GameServer.szServerName, pServerModify->szServerName, CountArray(pGameServerItem->m_GameServer.szServerName));
					lstrcpyn(pGameServerItem->m_GameServer.szServerAddr, pServerModify->szServerAddr, CountArray(pGameServerItem->m_GameServer.szServerAddr));

					//目录人数
					CGameKindItem * pGameKindItem = m_ServerListManager.SearchGameKind(pGameServerItem->m_GameServer.wKindID);
					if (pGameKindItem != NULL)
					{
						tagGameServer * pGameServer = &pGameServerItem->m_GameServer;
						pGameKindItem->m_GameKind.dwOnLineCount -= dwOldOnlineCount;
						pGameKindItem->m_GameKind.dwOnLineCount += pGameServer->dwOnLineCount;

						pGameKindItem->m_GameKind.dwFullCount -= dwOldFullCount;
						pGameKindItem->m_GameKind.dwFullCount += pGameServer->dwFullCount;
					}
				}

				return true;
			}
		case SUB_CS_S_SERVER_REMOVE:	//房间删除
			{
				//效验参数
				ASSERT(wDataSize == sizeof(CMD_CS_S_ServerRemove));
				if (wDataSize != sizeof(CMD_CS_S_ServerRemove)) return false;

				//变量定义
				CMD_CS_S_ServerRemove * pServerRemove = (CMD_CS_S_ServerRemove *)pData;

				//变量定义
				m_ServerListManager.DeleteGameServer(pServerRemove->wServerID);
				return true;
			}
		case SUB_CS_S_SERVER_FINISH:	//房间完成
			{
				//清理列表
				m_ServerListManager.CleanServerItem();

				//事件处理
				CP_ControlResult ControlResult;
				ControlResult.cbSuccess = ER_SUCCESS;
				SendUIControlPacket(UI_CORRESPOND_RESULT, &ControlResult, sizeof(ControlResult));

				return true;
			}
	
	}

	return true;
}


//控制事件
bool CAttemperEngineSink::OnEventControl(WORD wIdentifier, VOID * pData, WORD wDataSize)
{
	switch (wIdentifier)
	{
		case CT_CONNECT_CORRESPOND:		//连接协调
			{
				//发起连接
				tagAddressInfo * pCorrespondAddress = &m_pInitParameter->m_CorrespondAddress;
				m_pITCPSocketService->Connect(pCorrespondAddress->szAddress, m_pInitParameter->m_wCorrespondPort);

				//构造提示
				TCHAR szString[512] = TEXT("");
				_sntprintf(szString, CountArray(szString), TEXT("正在连接协调服务器 [ %s:%d ]"), pCorrespondAddress->szAddress, m_pInitParameter->m_wCorrespondPort);

				//提示消息
				CTraceService::TraceString(szString, TraceLevel_Normal);

				return true;
			}
	}

	return false;
}

//读取事件
bool CAttemperEngineSink::OnEventTCPNetworkRead(TCP_Command Command, VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	if (Command.wMainCmdID == MDM_GP_FRIENDSERVER)
	{
		switch (Command.wSubCmdID)
		{
			case SUB_GP_REGISTERUSER:  //用户注册
				{
					return OnRegisterUser(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_CREATEGROUP:  //创建群组
				{
					return OnCreateFriendGroup(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_JOINGROUP:    //加入群组
				{
					return OnJoinFriendGroup(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_DISMISSGROUP: //解散群组
				{
					return DeleteFriendGroup(pData,wDataSize,dwSocketID);
				}
			case SUB_GP_EXITGROUP:	 //退出群组
				{
					return OnExitFriendGroup(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_AUDITINGTRSULT: //审核结果
				{
					return OnAuditingResult(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_FOREACHGROUPLIST: //遍历群成员
				{
					return OnforEachGroupUserList(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_SELECTGROUPIDINFO: //查询群信息
				{
					return OnSelectGroupIDInfo(pData,wDataSize,dwSocketID);
				}
			case SUB_GP_GETGROUPROOMINFO: //查询房间信息
				{
					return OnGetGroupRoomInfo(pData,wDataSize,dwSocketID);
				}
			case SUB_GP_MODIYGROUPRULE:  //修改群规则
				{
					return OnModifyGroupRule(pData,wDataSize,dwSocketID);
				}
			default:
				break;
		}
	}
	else if (Command.wMainCmdID == MDM_GP_FRIEND_ROOM)
	{
		switch (Command.wSubCmdID)
		{
			case  SUB_GP_REGISTERSERVEICE:  //服务器注册
				{
					return OnRegisterServerice(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_CREATETABLEROOM:   //房间创建
				{
					return OnGroupCreateRoom(pData, wDataSize, dwSocketID);
				}
			case SUB_GP_MODITYTABLEROOM:  //房间修改
				{
					return OnGroupModityRoomStatus(pData,wDataSize,dwSocketID);
				}
			case SUB_GP_DELETETABLEROOM:  //房间删除
				{
					return OnGroupDeleteRoom(pData,wDataSize,dwSocketID);
				}
		}
	
	}

	return false;
}



//数据库事件
bool CAttemperEngineSink::OnEventDataBase(WORD wRequestID, DWORD dwContextID, VOID * pData, WORD wDataSize)
{
	switch (wRequestID)
	{

	}
	return false;
}


bool CAttemperEngineSink::InitGroup(DWORD KindID)
{
	ASSERT(KindID > 0);

	m_KindID = KindID;
	if (m_WhRedisServer.InitRedisServer() == false)
	{
		ASSERT(FALSE);
		CTraceService::TraceString(_T("redis连接失败"), TraceLevel_Exception);
		return false;
	}

	return true;
}

//用户注册
bool CAttemperEngineSink::OnRegisterUser(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_REGISTERUSER));
	if (wDataSize != sizeof(CMD_GP_REGISTERUSER))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("创建群消息结构大小不同 (CMD_GP_REGISTERUSER) 目标:%d 实际:%d"), sizeof(CMD_GP_REGISTERUSER), wDataSize);
		return false;
	}

	CMD_GP_REGISTERUSER * pCreateTable = (CMD_GP_REGISTERUSER*)pData;
	CPushLog(ARRAY_V(dwSocketID,SYSFRIENDLOG), LOG_DEBUG, _T("UserID:%d 注册好友服务器"), pCreateTable->dwUserID);

	//1:用户在线注册
	AddBindParameter(pCreateTable, dwSocketID,SOCKET_TYPE_USER);
	//2:我的群(加入与创建)
	SendMyGroup(pCreateTable->dwUserID, dwSocketID);
	//1：查询离线消息
	GetUserOfflineMsg(pCreateTable->dwUserID, dwSocketID);

	return true;
}

//注册服务器
bool CAttemperEngineSink::OnRegisterServerice(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	//注册服务器信息
	CMD_GP_REGISTERUSER * pCreateTable = (CMD_GP_REGISTERUSER*)pData;
	AddBindParameter(pCreateTable, dwSocketID, SOCKET_TYPE_SERVERICE);
	
	//拉取服务俱乐部团  ->redis 
	//m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIEND_ROOM, SUB_GP_GETGROUPALLSERVER);
	
	return true;
}

//创建群组
bool CAttemperEngineSink::OnCreateFriendGroup(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_CREATEGROUP));
	if (wDataSize != sizeof(CMD_GP_CREATEGROUP))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("创建群消息结构大小不同 (CMD_GP_CREATEGROUP) 目标:%d 实际:%d"), sizeof(CMD_GP_CREATEGROUP), wDataSize);
		return false;
	}

	CMD_GP_CREATEGROUP * pCreateTable = (CMD_GP_CREATEGROUP*)pData;
	CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_DEBUG, _T("UserID:%d 创建亲友团", pCreateTable->dwUserID));

	////检查UserID 创建次数
	char RedisCmdLine[100]; // Group:GroupUserCreateOwner
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, pCreateTable->dwUserID);

	int CreateCnt = m_WhRedisServer.HashSize(RedisCmdLine);
	if (CreateCnt >= MAX_CREATE)
	{
		//提示创建次数过多
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_CREATEGROUPFIAL);
		CPushLog(ARRAY_V(dwSocketID,SYSFRIENDLOG), LOG_DEBUG, _T("UserID:%d 创建亲友团过多", pCreateTable->dwUserID));
		return true;
	}

	tagBindParameter *BindParameter = GetBindParameterToUser(pCreateTable->dwUserID);
	if (BindParameter != NULL)
	{
		//1:记录群信息 用户创建群信息 1->N
		int GroupId = GetGroupUUID();
		SerializationGroupInfoToRedis(pCreateTable, GroupId, BindParameter->pUserInfo, GroupType_Create,0);

		//2:发送创建完成
		CMD_GP_CREATESUCCESS CreateSuccess;
		ZeroMemory(&CreateSuccess, sizeof(CreateSuccess));
		CreateSuccess.dwGroupID = GroupId;
		lstrcpyn(CreateSuccess.szGroupBossNickName, BindParameter->pUserInfo.szNickName, CountArray(CreateSuccess.szGroupBossNickName));
		memcpy(&CreateSuccess.mCreateInfo, pCreateTable, sizeof(CreateSuccess.mCreateInfo));
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_CREATEGROUPSUCCESS, &CreateSuccess, sizeof(CreateSuccess));

		CString msGroupID;
		msGroupID.Format(_T("CLUB_%d"),GroupId);
		CServerPushLog::SharedLog()->SetSocketUserID(msGroupID, CLUBLOG + GroupId);
		CPushLog(ARRAY_V(dwSocketID, CLUBLOG + GroupId), LOG_DEBUG, _T("亲友团创建成功 群主:%s"), BindParameter->pUserInfo.szNickName);

		//3:群用户列表(N)
		GroupUserListInfo  UserInfo;
		ZeroMemory(&UserInfo, sizeof(UserInfo));
		UserInfo.dwUserID = pCreateTable->dwUserID;
		UserInfo.dwGameID = BindParameter->pUserInfo.dwGameID;
		UserInfo.dwGropuID = GroupId;
		lstrcpyn(UserInfo.szNickName, BindParameter->pUserInfo.szNickName, CountArray(UserInfo.szNickName));
		lstrcpyn(UserInfo.szWxHeadUrl, BindParameter->pUserInfo.szWxHeadUrl, CountArray(UserInfo.szWxHeadUrl));
		AddUserToRedisGroup(UserInfo);
		CPushLog(ARRAY_V(dwSocketID, CLUBLOG + GroupId), LOG_DEBUG, _T("群成员信息:UserID:%d GameID:%d 群号:%d 昵称:%s  头像:%s"),pCreateTable->dwUserID, UserInfo.dwGameID
			,GroupId,BindParameter->pUserInfo.szNickName, UserInfo.szWxHeadUrl);

		//写群号对应群主关系 (1-1)
		char szGroupID[100];
		snprintf(szGroupID, sizeof(szGroupID), "%d", GroupId);
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);  // Group:GroupIdToOwnerID 群ID对应群主ID
		m_WhRedisServer.ZAddArrayBufferData(RedisCmdLine, (void*)szGroupID, strlen(szGroupID), (SCORE)pCreateTable->dwUserID);

		//写日志..
		TCHAR szDesc[128];
		_sntprintf(szDesc, CountArray(szDesc), TEXT("用户:[%d]创建亲友团[%d]成功"),pCreateTable->dwUserID,GroupId);
		RecordGroupLog(GroupId,pCreateTable->dwUserID,szDesc);

		//改变用户属性
		ChangeUserAttribute(GroupId, pCreateTable->dwUserID, GroupType_JOIN,_T(""));
	}


	return true;
}

//加入群组
bool CAttemperEngineSink::OnJoinFriendGroup(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_JOINGROUP));
	if (wDataSize != sizeof(CMD_GP_JOINGROUP))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("加入群消息结构大小不同 (CMD_GP_CREATEGROUP) 目标:%d 实际:%d"), sizeof(CMD_GP_JOINGROUP), wDataSize);
		return false;
	}

	CMD_GP_JOINGROUP * pJoinGroup = (CMD_GP_JOINGROUP*)pData;
	CPushLog(ARRAY_V(dwSocketID,pJoinGroup->dwJoinGroupID+CLUBLOG), LOG_DEBUG, _T("UserID:%d 加入亲友团 群号:%d",pJoinGroup->dwJoinGroupID+CLUBLOG));

	//1:查找群主ID
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	DWORD GroupMainID = m_WhRedisServer.GetListIndexScore(RedisCmdLine, pJoinGroup->dwJoinGroupID);
	if (GroupMainID == 0)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("根据群号查找不到群主 :%d"), pJoinGroup->dwJoinGroupID);
		OnSendPublicMessage(dwSocketID, 0, _T("输入的群号不存在!"));
		return true;
	}

	//2:自己加自己
	if (GroupMainID == pJoinGroup->dwUserID)
	{
		OnSendPublicMessage(dwSocketID, 0, _T("您已经是群主不能再次加入!"));
		CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("您已经是群主不能再次加入"));
		return true;
	}

	//3:验证是否已经存在
	tagBindParameter* JoinUser = GetBindParameterToUser(pJoinGroup->dwUserID);
	ASSERT(JoinUser != NULL);
	if (JoinUser == NULL)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("查不到此人在线信息 UserID:%d", pJoinGroup->dwUserID));
		return true;
	}

	GroupUserListInfo  UserInfo;
	ZeroMemory(&UserInfo, sizeof(UserInfo));
	UserInfo.dwUserID = pJoinGroup->dwUserID;
	UserInfo.dwGameID = JoinUser->pUserInfo.dwGameID;
	UserInfo.dwGropuID = pJoinGroup->dwJoinGroupID;
	lstrcpyn(UserInfo.szNickName, JoinUser->pUserInfo.szNickName, CountArray(UserInfo.szNickName));
	if (JoinUser != NULL)lstrcpyn(UserInfo.szWxHeadUrl, JoinUser->pUserInfo.szWxHeadUrl, CountArray(UserInfo.szWxHeadUrl));
	else lstrcpyn(UserInfo.szWxHeadUrl, _T(""), CountArray(UserInfo.szWxHeadUrl));

	bool RetRelut = CheckUserInGroup(UserInfo);
	if (RetRelut)
	{
		OnSendPublicMessage(dwSocketID, 0, _T("您已经在该群内 无需再次申请加入!"));
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("您已经在该群内 无需再次加入 UserID:%d", pJoinGroup->dwUserID));
		return true;
	}

	//4:用户消息缓存 
	bool bRet = OwnerOfflineMessage(UserInfo, GroupMainID, OPERATION_ADD, JoinUser->pUserInfo.dwGameID);
	CPushLog(ARRAY_V(pJoinGroup->dwJoinGroupID), LOG_DEBUG, _T("用户申请UserID:%d 昵称:%s 缓存数据"), pJoinGroup->dwUserID, JoinUser->pUserInfo.szNickName);
	if (!bRet)
	{
		OnSendPublicMessage(dwSocketID, 0, _T("您已经申请该群无需再次加入!"));
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("您已经申请该群 无需再次申請 UserID:%d", pJoinGroup->dwUserID));
		return true;
	}

	//5:查找群主在线
	tagBindParameter *bindParameter = GetBindParameterToUser(GroupMainID);
	if (bindParameter != NULL)
	{
		//2:查找群主scoketID
		DWORD dwGroupSocketID = bindParameter->dwSocketID;
		if (dwGroupSocketID != 0)  //如果在线
		{
			CPushLog(ARRAY_V(pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("用户申请UserID:%d 昵称:%s 通知群主审核"), pJoinGroup->dwUserID, JoinUser->pUserInfo.szNickName);

			CMD_GP_AUDITINGLEAGUER CmdAuditingLeaguer;
			ZeroMemory(&CmdAuditingLeaguer, sizeof(CmdAuditingLeaguer));
			tagBindParameter *pJionUserInfo = GetBindParameterToUser(pJoinGroup->dwUserID);
			if (pJionUserInfo != NULL)
			{
				CmdAuditingLeaguer.IndexMsg = JoinUser->pUserInfo.dwGameID;
				CmdAuditingLeaguer.dwGroupID = pJoinGroup->dwJoinGroupID;
				CmdAuditingLeaguer.dwGameID = pJionUserInfo->pUserInfo.dwGameID;
				CmdAuditingLeaguer.dwUserID = pJionUserInfo->pUserInfo.dwUserID;
				lstrcpyn(CmdAuditingLeaguer.szNickName, pJionUserInfo->pUserInfo.szNickName, CountArray(CmdAuditingLeaguer.szNickName));
				lstrcpyn(CmdAuditingLeaguer.szWxHeadUrl, pJionUserInfo->pUserInfo.szWxHeadUrl, CountArray(CmdAuditingLeaguer.szWxHeadUrl));
				m_pITCPNetworkEngine->SendData(dwGroupSocketID, MDM_GP_FRIENDSERVER, SUB_GP_NOTICEGROUPAUDIT, &CmdAuditingLeaguer, sizeof(CmdAuditingLeaguer));
			}
			else
			{
				ASSERT(0);
				CPushLog(ARRAY_V(SYSFRIENDLOG,pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("加入用户查找不到该属性"));
			}
		}
	}

	TCHAR szDesc[128];
	_sntprintf(szDesc, CountArray(szDesc), TEXT("用户:[%d]申请加入亲友团[%d]"), pJoinGroup->dwUserID,pJoinGroup->dwJoinGroupID);
	RecordGroupLog(pJoinGroup->dwJoinGroupID, pJoinGroup->dwUserID, szDesc);
	//等待审核
	m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_NOTICEUSERAUDIT);
	CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("用户:[%d]申请加入亲友团[%d]"),pJoinGroup->dwUserID, pJoinGroup->dwJoinGroupID);

	return true;
}

//退出群组
bool CAttemperEngineSink::OnExitFriendGroup(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_EXITGROUP));
	if (wDataSize != sizeof(CMD_GP_EXITGROUP))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("退出群消息结构大小不同 (CMD_GP_CREATEGROUP) 目标:%d 实际:%d"), sizeof(CMD_GP_EXITGROUP), wDataSize);
		return false;
	}

	CMD_GP_EXITGROUP * pJoinGroup = (CMD_GP_EXITGROUP*)pData;
	CPushLog(ARRAY_V(dwSocketID,pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("退出群消息 UserID:%d 群号:%d"), pJoinGroup->dwUserID,pJoinGroup->dwJoinGroupID+CLUBLOG);

	//1：验证群号
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	DWORD GroupMainID = m_WhRedisServer.GetListIndexScore(RedisCmdLine, pJoinGroup->dwJoinGroupID);
	if (GroupMainID == 0)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("根据群号查找不到群主 :%d"), pJoinGroup->dwJoinGroupID);
		OnSendPublicMessage(dwSocketID, 0, _T("输入的群号不存在!"));
		return true;
	}

	//2:验证群主
	if (GroupMainID == pJoinGroup->dwUserID)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG,pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("您是群主不能直接退出本群 :%d"), pJoinGroup->dwJoinGroupID);
		OnSendPublicMessage(dwSocketID, 0, _T("您是群主不能直接退出本群!"));
		return true;
	}

	//3:验证群成员
	GroupUserListInfo  UserInfo;
	ZeroMemory(&UserInfo, sizeof(UserInfo));
	UserInfo.dwUserID = pJoinGroup->dwUserID;
	UserInfo.dwGropuID = pJoinGroup->dwJoinGroupID;
	
	bool RetRelut = CheckUserInGroup(UserInfo);
	if (!RetRelut)
	{
		OnSendPublicMessage(dwSocketID, 0, _T("您不在本群!"));
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_ERROR, _T("出现异常 不在本群 %d 群号:%d"), UserInfo.dwUserID, pJoinGroup->dwJoinGroupID);
		return true;
	}

	//4：删除用户该群信息
	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERJION, m_KindID, pJoinGroup->dwUserID);
	bool RetIsSuccess = m_WhRedisServer.DeleteHashValueToScore(RedisCmdLine, pJoinGroup->dwJoinGroupID, pJoinGroup->dwJoinGroupID);
	CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID+ CLUBLOG), LOG_DEBUG, _T("删除自己加入的群信息 :%d"), RetIsSuccess);

	//5:删除群成员
	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, pJoinGroup->dwJoinGroupID);
	RetIsSuccess = m_WhRedisServer.DeleteHashValueToScore(RedisCmdLine, pJoinGroup->dwUserID, pJoinGroup->dwUserID);
	if (RetIsSuccess)
	{
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_EXITGROUPSUCCESS, pData, wDataSize);
	}
	else
	{
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_EXITGROUPFAIL, pData, wDataSize);
	}

	CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("删除群成员信息 :%d"), RetIsSuccess);

	//被动离开 通知用户
	if (pJoinGroup->cbpassive == 2)
	{
		CMD_GP_OPERATIONDESC OperationDesc;
		ZeroMemory(&OperationDesc, sizeof(OperationDesc));
		_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已将[%s]移除本群"), pJoinGroup->szNickName);
		//给群主发确认操作
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));
	
		tagBindParameter * pBindParameter = GetBindParameterToUser(pJoinGroup->dwUserID);
		if (pBindParameter != NULL)
		{
			m_pITCPNetworkEngine->SendData(pBindParameter->dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_EXITGROUPSUCCESS, pData, wDataSize);
		
			_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已被移除[%d]群"), pJoinGroup->dwJoinGroupID);
			//给群主发确认操作
			m_pITCPNetworkEngine->SendData(pBindParameter->dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));
		}

		CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("您已被移除:%d 群"), pJoinGroup->dwJoinGroupID);
	}
	else
	{
		//通知自己
		CMD_GP_OPERATIONDESC OperationDesc;
		ZeroMemory(&OperationDesc, sizeof(OperationDesc));
		_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已成功离开[%d]群"), pJoinGroup->dwJoinGroupID);
		//给群主发确认操作
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));
	
		//通知群主
		if (GroupMainID!=0)
		{
			tagBindParameter * pBindParameter = GetBindParameterToUser(GroupMainID);
			if (pBindParameter != NULL)
			{
				ZeroMemory(&OperationDesc, sizeof(OperationDesc));
				_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("[%s]已离开[%d]群"), pJoinGroup->szNickName, pJoinGroup->dwJoinGroupID);
				//给群主发确认操作
				m_pITCPNetworkEngine->SendData(pBindParameter->dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));
			}
		}

		CPushLog(ARRAY_V(dwSocketID, pJoinGroup->dwJoinGroupID + CLUBLOG), LOG_DEBUG, _T("您已成功离开:%d 群"), pJoinGroup->dwJoinGroupID);
	}

	TCHAR szDesc[128];
	if (pJoinGroup->cbpassive == 1)
	{
		_sntprintf(szDesc, CountArray(szDesc), TEXT("用户:[%d]退出亲友团[%d] 模式:主动"), pJoinGroup->dwUserID, pJoinGroup->dwJoinGroupID);
	}
	else
	{
		_sntprintf(szDesc, CountArray(szDesc), TEXT("用户:[%d]退出亲友团[%d] 模式:被动"), pJoinGroup->dwUserID, pJoinGroup->dwJoinGroupID);
	}
	RecordGroupLog(pJoinGroup->dwJoinGroupID, pJoinGroup->dwUserID, szDesc);

	//改变用户属性
	ChangeUserAttribute(pJoinGroup->dwJoinGroupID, pJoinGroup->dwUserID, GroupType_EXIT, _T(""));
	return true;
}

//删除群组
bool CAttemperEngineSink::DeleteFriendGroup(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_DELETEGROUP));
	if (wDataSize != sizeof(CMD_GP_DELETEGROUP))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("删除群组 (CMD_GP_DELETEGROUP) 目标:%d 实际:%d"), sizeof(CMD_GP_DELETEGROUP), wDataSize);
		return false;
	}

	CMD_GP_DELETEGROUP * pResult = (CMD_GP_DELETEGROUP*)pData;
	CPushLog(ARRAY_V(dwSocketID, pResult->dwGropuID + CLUBLOG), LOG_DEBUG, _T("删除群组消息:%d 群 UserID:%d"), pResult->dwGropuID,pResult->dwUserID);

	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	DWORD GroupMainID = m_WhRedisServer.GetListIndexScore(RedisCmdLine, pResult->dwGropuID);
	if (GroupMainID == 0)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pResult->dwGropuID+CLUBLOG), LOG_ERROR, _T("根据群号查找不到群主 :%d"), pResult->dwGropuID);
		OnSendPublicMessage(dwSocketID, 0, _T("输入的群号不存在!"));
		return true;
	}

	//验证群主
	if (GroupMainID != pResult->dwUserID)
	{
		CPushLog(ARRAY_V(dwSocketID,SYSFRIENDLOG, pResult->dwGropuID + CLUBLOG),LOG_ERROR,_T("群主条件不符合"));
		return true;
	}

	//查询群成员是否在玩
	CMD_CS_C_FINDGROUPPLAY  FindGroupPlay;
	FindGroupPlay.dwGroupID = pResult->dwGropuID;
	FindGroupPlay.dwUserID = pResult->dwUserID;
	FindGroupPlay.dwScoketID = dwSocketID;
	m_pITCPSocketService->SendData(MDM_CS_SERVICE_INFO, SUB_CS_S_SEARCH_GROUPPLAYING,&FindGroupPlay,sizeof(FindGroupPlay));
	CPushLog(ARRAY_V(dwSocketID, pResult->dwGropuID + CLUBLOG), LOG_ERROR, _T("群主查询服务器在线人数"));
	return true;
}

//查询群信息
bool CAttemperEngineSink::OnSelectGroupIDInfo(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_GetGroupInfo));
	if (wDataSize != sizeof(CMD_GP_GetGroupInfo))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("查找群ID (CMD_GP_GetGroupInfo) 目标:%d 实际:%d"), sizeof(CMD_GP_GetGroupInfo), wDataSize);
		return false;
	}

	CMD_GP_GetGroupInfo * pResult = (CMD_GP_GetGroupInfo*)pData;
	CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("用户:%d 查找群ID 群号:%d"), pResult->dwUserID,pResult->dwGroupID);

	//1：验证群号
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	DWORD GroupMainID = m_WhRedisServer.GetListIndexScore(RedisCmdLine, pResult->dwGroupID);
	if (GroupMainID == 0)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("根据群号查找不到群主 :%d"), pResult->dwGroupID);
		OnSendPublicMessage(dwSocketID, 0, _T("输入的群号不存在!"));
		return true;
	}

	CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("用户:%d 查找群ID 群号:%d 群主ID:%d"), pResult->dwUserID, pResult->dwGroupID,GroupMainID);

	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	//验证在线发送进群
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, GroupMainID);
	std::string RelutJsonValue = m_WhRedisServer.GetHashIndexToValue(RedisCmdLine, pResult->dwGroupID);
	GroupInfoEx *mGroupInfo = (GroupInfoEx*)RelutJsonValue.c_str();
	 
	if (mGroupInfo != NULL)
	{
		ZeroMemory(RedisCmdLine, sizeof(char) * 100);
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, pResult->dwGroupID);
		int ListSizeCount = m_WhRedisServer.HashSize(RedisCmdLine);
		mGroupInfo->dwGroupUserCnt = ListSizeCount > 0 ? ListSizeCount : 0;
		mGroupInfo->dwGroupRoomCnt = m_GroupRoomManager.GetGroupArray(pResult->dwGroupID).size();
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPINFORESULT, mGroupInfo, sizeof(GroupInfoEx));
		CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("用户:%d 查找群ID 群号:%d 群数据完成"), pResult->dwUserID, pResult->dwGroupID);
		return true;
	}

	CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("用户:%d 查找群ID 群号:%d 群数据异常"), pResult->dwUserID, pResult->dwGroupID);

	return true;
}


//审核操作(群主)
bool CAttemperEngineSink::OnAuditingResult(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_AUDITINGTRSULT));
	if (wDataSize != sizeof(CMD_GP_AUDITINGTRSULT))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("审核操作 (CMD_GP_AUDITINGTRSULT) 目标:%d 实际:%d"), sizeof(CMD_GP_EXITGROUP), wDataSize);
		return false;
	}

	CMD_GP_AUDITINGTRSULT * pResult = (CMD_GP_AUDITINGTRSULT*)pData;
	CPushLog(ARRAY_V(dwSocketID,pResult->dwGroupID+CLUBLOG), LOG_DEBUG, _T("群主审核操作 UserID:%d 群号:%d 类型:%d"), pResult->dwUserID,pResult->dwGroupID,pResult->OperationType);

	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPOWNEROFFLINEMESG, m_KindID, pResult->dwUserID);

	//1：查找离线消息 
	double  Score = double(pResult->dwGroupID) + ((double)(pResult->IndexMsg) / double(1000000));   
	std::string RelutJsonValue = m_WhRedisServer.GetHashIndexToValue_d(RedisCmdLine, Score);
	ASSERT(RelutJsonValue.empty() == false);
	//2：清空离线消息
	m_WhRedisServer.DeleteHashValueToScore_d(RedisCmdLine, Score, Score);
	//3：异常处理
	if (RelutJsonValue.empty())
	{
		CTraceService::TraceString(_T("获取离线消息失败"), TraceLevel_Exception);
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG,pResult->dwGroupID+CLUBLOG), LOG_ERROR, _T("UserID:%d 处理离线消息异常 Index:%I64d"), pResult->dwUserID, pResult->IndexMsg);
		return true;
	}
	//3：加入还是退出 对应操作
	GroupOffileMessage *OffIleMessage = (GroupOffileMessage*)RelutJsonValue.c_str();  //UnSerializationOffileMsg(RelutJsonValue);

	tagBindParameter * mBindParameter = GetBindParameterToUser(OffIleMessage->dwUserID);

	if (pResult->OperationType == 1) //同意加入
	{
		//加入进群
		GroupUserListInfo  UserInfo;
		ZeroMemory(&UserInfo, sizeof(UserInfo));
		UserInfo.dwUserID = OffIleMessage->dwUserID;
		UserInfo.dwGameID = OffIleMessage->dwGameID;
		UserInfo.dwGropuID = OffIleMessage->dwGroupID;
		lstrcpyn(UserInfo.szNickName, OffIleMessage->szNickName, CountArray(OffIleMessage->szNickName));
		lstrcpyn(UserInfo.szWxHeadUrl, OffIleMessage->szWxHeadUrl, CountArray(OffIleMessage->szWxHeadUrl));
		AddUserToRedisGroup(UserInfo);
		//改变用户群关系
		ChangeUserAttribute(OffIleMessage->dwGroupID, OffIleMessage->dwUserID, GroupType_JOIN, _T(""));
		CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("UserID:%d GameID:%d dwGropuID:%d 昵称:%s 头像:%s 群主同意加入俱乐部"), UserInfo.dwUserID,UserInfo.dwGameID,UserInfo.dwGropuID, OffIleMessage->szNickName, OffIleMessage->szWxHeadUrl);
		
		//验证在线发送进群
		char RedisCmdLine[100];
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, pResult->dwUserID);
		std::string RelutJsonValue = m_WhRedisServer.GetHashIndexToValue(RedisCmdLine, UserInfo.dwGropuID);
		GroupInfoEx *mGroupInfo = (GroupInfoEx*)RelutJsonValue.c_str();
		if (RelutJsonValue.empty() == false)
		{
			lstrcpyn(UserInfo.szNickName,mGroupInfo->mBaseGroupData.szGroupBossNickName,CountArray(UserInfo.szNickName));
			lstrcpyn(UserInfo.szWxHeadUrl,mGroupInfo->mBaseGroupData.szGroupBossWxHeadUrl,CountArray(UserInfo.szWxHeadUrl));
			//1:获得群信息
			if (mBindParameter != NULL)
			{
				SerializationGroupInfoToRedis(&(mGroupInfo->mBaseGroupData.mCreateGroup), UserInfo.dwGropuID, UserInfo, GroupType_JOIN, mBindParameter->dwSocketID);
			}
			else
			{
				SerializationGroupInfoToRedis(&(mGroupInfo->mBaseGroupData.mCreateGroup), UserInfo.dwGropuID, UserInfo, GroupType_JOIN,0);
			}
		}

		CMD_GP_OPERATIONDESC OperationDesc;
		ZeroMemory(&OperationDesc, sizeof(OperationDesc));
		_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已成功加入[%d]群"), UserInfo.dwGropuID);
		if (mBindParameter != NULL)  //在线提示失败消息
		{
			m_pITCPNetworkEngine->SendData(mBindParameter->dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_NOTICEGROUPNUMBER, &OperationDesc, sizeof(OperationDesc));
		}
	}
	else
	{
		if (mBindParameter != NULL)  //在线提示失败消息
		{
			TCHAR szDesc[128];
			_sntprintf(szDesc, CountArray(szDesc), TEXT("群主拒绝您加入[%d]群"), OffIleMessage->dwGroupID);
			//给对方提示消息
			OnSendPublicMessage(mBindParameter->dwSocketID, 200, szDesc);

			CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("UserID:%d  dwGropuID:%d  群主拒绝加入俱乐部"), pResult->dwUserID, pResult->dwGroupID);
		}
	}

	CMD_GP_OPERATIONDESC OperationDesc;
	ZeroMemory(&OperationDesc,sizeof(OperationDesc));
	if (pResult->OperationType == 1)
	{
		_sntprintf(OperationDesc.szDesc,CountArray(OperationDesc.szDesc), _T("您已同意[%s]加入本群"), OffIleMessage->szNickName);
	}
	else if(pResult->OperationType == 2)
	{
		_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("您已拒绝[%s]加入本群"), OffIleMessage->szNickName);
	}
	//给群主发确认操作
	m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_NOTICEGROUPADMIN,&OperationDesc,sizeof(OperationDesc));

	TCHAR szDesc[128];
	if (pResult->OperationType == 1)
	{
		_sntprintf(szDesc, CountArray(szDesc), TEXT("群主审核用户:[%d]进入亲友团 审核结果：通过"), OffIleMessage->dwUserID);
	}
	else
	{
		_sntprintf(szDesc, CountArray(szDesc), TEXT("群主审核用户:[%d]进入亲友团 审核结果 拒绝"), OffIleMessage->dwUserID);
	}
	RecordGroupLog(OffIleMessage->dwUserID, pResult->dwUserID, szDesc);

	CPushLog(ARRAY_V(dwSocketID, pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("群主审核俱乐部完成"));
	return true;
}


//公共消息
bool CAttemperEngineSink::OnSendPublicMessage(DWORD dwSocketID, int Code, TCHAR szMsg[128])
{
	CMD_GP_GroupFailureMessage GroupMessage;
	ZeroMemory(&GroupMessage, sizeof(GroupMessage));
	GroupMessage.lResultCode = Code;
	lstrcpyn(GroupMessage.szDescribeString, szMsg, CountArray(GroupMessage.szDescribeString));
	m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_PUBLICMESSAGE, &GroupMessage, sizeof(GroupMessage));
	return true;
}

//创建群组序列化
void CAttemperEngineSink::SerializationGroupInfoToRedis(CMD_GP_CREATEGROUP * pCreateTable, DWORD dwGroupId, GroupUserListInfo UserInfo, enGroupTyep GroupType,DWORD dwSocketID)
{
	GroupInfoEx mGroupInfo;
	ZeroMemory(&mGroupInfo, sizeof(mGroupInfo));
	mGroupInfo.mBaseGroupData.dwGroupID = dwGroupId;
	mGroupInfo.mBaseGroupData.cbByte = GroupType;
	lstrcpyn(mGroupInfo.mBaseGroupData.szGroupBossNickName, UserInfo.szNickName, CountArray(mGroupInfo.mBaseGroupData.szGroupBossNickName));
	lstrcpyn(mGroupInfo.mBaseGroupData.szGroupBossWxHeadUrl, UserInfo.szWxHeadUrl, CountArray(mGroupInfo.mBaseGroupData.szGroupBossWxHeadUrl));
	mGroupInfo.mBaseGroupData.mCreateGroup.dwUserID = pCreateTable->dwUserID;
	mGroupInfo.mBaseGroupData.mCreateGroup.dwGameID = pCreateTable->dwGameID;
	lstrcpyn(mGroupInfo.mBaseGroupData.mCreateGroup.GroupName, pCreateTable->GroupName, CountArray(pCreateTable->GroupName));
	mGroupInfo.mBaseGroupData.mCreateGroup.cbDrawCountLimit = pCreateTable->cbDrawCountLimit;
	mGroupInfo.mBaseGroupData.mCreateGroup.cbJoinGamePeopleCount = pCreateTable->cbJoinGamePeopleCount;
	mGroupInfo.mBaseGroupData.mCreateGroup.cbPayMode = pCreateTable->cbPayMode;
	CopyMemory(mGroupInfo.mBaseGroupData.mCreateGroup.cbGameRule, pCreateTable->cbGameRule, sizeof(mGroupInfo.mBaseGroupData.mCreateGroup.cbGameRule));
	mGroupInfo.dwGroupUserCnt = 0;
	mGroupInfo.dwGroupRoomCnt = 0;

	//检查UserID 创建次数
	char RedisCmdLine[100];
	
	if (GroupType == GroupType_Create)  // 0
	{
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, UserInfo.dwUserID);// "Group:GroupUserCreateOwner"  //用户创建群列表
		m_WhRedisServer.ZAddArrayBufferData(RedisCmdLine, &mGroupInfo, sizeof(mGroupInfo), dwGroupId);
	}
	else if(GroupType == GroupType_JOIN)  // 1
	{
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERJION, m_KindID, UserInfo.dwUserID); // "Group:GroupUserJoin" //用户加入群列表
		m_WhRedisServer.ZAddArrayBufferData(RedisCmdLine, &mGroupInfo, sizeof(mGroupInfo), dwGroupId);
	}
	
	if (GroupType == GroupType_JOIN && dwSocketID!=0)
	{
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID,dwGroupId);
		int ListSizeCount = m_WhRedisServer.HashSize(RedisCmdLine);
		mGroupInfo.dwGroupUserCnt = ListSizeCount > 0 ? ListSizeCount : 0;
		mGroupInfo.dwGroupRoomCnt = m_GroupRoomManager.GetGroupArray(mGroupInfo.mBaseGroupData.dwGroupID).size();
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_JOINGROUPSUCCESS, &mGroupInfo, sizeof(mGroupInfo));
	}

	return;
}



//检查是否在群内
bool CAttemperEngineSink::CheckUserInGroup(GroupUserListInfo UserInfo)
{
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, UserInfo.dwGropuID);//"Group:GroupUserInfoList" //群群员列表
	//校验是否存在
	std::string retstr = m_WhRedisServer.GetHashIndexToValue(RedisCmdLine, UserInfo.dwUserID);
	return !retstr.empty();
}


//用户加入redis
bool CAttemperEngineSink::AddUserToRedisGroup(GroupUserListInfo UserInfo)
{
	bool CheckRet = CheckUserInGroup(UserInfo);

	if (CheckRet == false)
	{
		char RedisCmdLine[100];
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, UserInfo.dwGropuID);//"Group:GroupUserInfoList" //群群员列表
		m_WhRedisServer.ZAddArrayBufferData(RedisCmdLine, (void*)&UserInfo, sizeof(UserInfo), UserInfo.dwUserID);
		return true;
	}

	return CheckRet;
}

//用户离线消息
bool CAttemperEngineSink::OwnerOfflineMessage(GroupUserListInfo UserInfo, DWORD WriteUID, BYTE type, SCORE Currnettime)
{
	GroupOffileMessage  mOffileMsg;
	ZeroMemory(&mOffileMsg, sizeof(mOffileMsg));
	mOffileMsg.dwUserID = UserInfo.dwUserID;
	mOffileMsg.dwGameID = UserInfo.dwGameID;
	mOffileMsg.dwGroupID = UserInfo.dwGropuID;
	mOffileMsg.cbType = type;
	mOffileMsg.IndexMsg = Currnettime;
	lstrcpyn(mOffileMsg.szNickName, UserInfo.szNickName, CountArray(UserInfo.szNickName));
	lstrcpyn(mOffileMsg.szWxHeadUrl, UserInfo.szWxHeadUrl, CountArray(UserInfo.szWxHeadUrl));

	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPOWNEROFFLINEMESG, m_KindID, WriteUID);

	double  Score =  double(UserInfo.dwGropuID) +  ((double)(UserInfo.dwGameID) / double(1000000));
	std::string retstr = m_WhRedisServer.GetHashIndexToValue_d(RedisCmdLine, Score);
	//校验是否存在
	//bool CheckRet = m_WhRedisServer.CheckArrayBufferData(RedisCmdLine, &mOffileMsg);
	if (retstr.empty())
	{
		ZeroMemory(RedisCmdLine, sizeof(char) * 100);
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPOWNEROFFLINEMESG, m_KindID, WriteUID);
		m_WhRedisServer.ZAddArrayBufferData_d(RedisCmdLine, &mOffileMsg, sizeof(mOffileMsg), Score);  //(SCORE)time(NULL)
		return true;
	}

	return false;
}


//获取离线消息
bool CAttemperEngineSink::GetUserOfflineMsg(DWORD ReadUserID, DWORD dwScoketID)
{
	//查找离线消息
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPOWNEROFFLINEMESG, m_KindID, ReadUserID);
	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];

	if (dwDataLenArray.size() > 0)  //有缓存
	{
		for (int i = 0; i < dwDataLenArray.size(); i++)
		{
			if (dwDataLenArray.at(i) < SOCKET_TCP_PACKET)
			{
				if ((wSendSize + dwDataLenArray[i]) > sizeof(cbDataBuffer))
				{
					m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_GETUSERMESSAGE, cbDataBuffer, wSendSize);
					wSendSize = 0;
				}

				CopyMemory(cbDataBuffer + wSendSize, strValueArray[i].c_str(), dwDataLenArray[i]);
				wSendSize += dwDataLenArray[i];
			}
			else
			{
				CPushLog(ARRAY_V(dwScoketID, SYSFRIENDLOG), LOG_ERROR, _T("UserID:%d 获取离线消息异常"), ReadUserID);
				ASSERT(0);
			}
		}

		if (wSendSize > 0 && dwScoketID != 0)
		{
			m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_GETUSERMESSAGE, cbDataBuffer, wSendSize);
		}
	}

	CPushLog(ARRAY_V(ReadUserID, SYSFRIENDLOG), LOG_DEBUG, _T("UserID:%d 获取离线消息数量:%d"), ReadUserID, dwDataLenArray.size());
	
	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);
	return true;
}

//发送自己创建的群
bool CAttemperEngineSink::SendMyGroup(DWORD dwUserID, DWORD dwScoketID)
{
	//查找离线消息
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, dwUserID);
	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];
	std::vector<DWORD> mMyCreateGroupIDArray;
	mMyCreateGroupIDArray.clear();

	if (dwDataLenArray.size() > 0)  //有缓存
	{
		for (int i = 0; i < dwDataLenArray.size(); i++)
		{
			if (dwDataLenArray.at(i) < SOCKET_TCP_PACKET)
			{
				if ((wSendSize + sizeof(GroupInfoEx)) > sizeof(cbDataBuffer))
				{
					m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_MYCREATEGROUP, cbDataBuffer, wSendSize);
					wSendSize = 0;
				}

				GroupInfoEx *mGroupStrcut = (GroupInfoEx*)strValueArray[i].c_str();
				mMyCreateGroupIDArray.push_back(mGroupStrcut->mBaseGroupData.dwGroupID);
				snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, mGroupStrcut->mBaseGroupData.dwGroupID);
				int ListSizeCount = m_WhRedisServer.HashSize(RedisCmdLine);
				mGroupStrcut->dwGroupUserCnt = ListSizeCount > 0 ? ListSizeCount : 0;
				mGroupStrcut->dwGroupRoomCnt = m_GroupRoomManager.GetGroupArray(mGroupStrcut->mBaseGroupData.dwGroupID).size();
				CopyMemory(cbDataBuffer + wSendSize, mGroupStrcut, sizeof(GroupInfoEx));
				wSendSize += sizeof(GroupInfoEx);
			}
			else
			{
				CPushLog(ARRAY_V(dwScoketID, SYSFRIENDLOG), LOG_ERROR, _T("UserID:%d 获取自己群消息异常"), dwScoketID);
				ASSERT(0);
			}
		}

		if (wSendSize > 0 && dwScoketID != 0)
		{
			m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_MYCREATEGROUP, cbDataBuffer, wSendSize);
		}
	}

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);
	
	CPushLog(ARRAY_V(dwUserID,SYSFRIENDLOG),LOG_DEBUG,_T("dwUserID:%d 创建的俱乐部数量:%d"),dwUserID,mMyCreateGroupIDArray.size());
 
	//遍历自己创建的群的所有房间号
	 SelectGroupID(mMyCreateGroupIDArray, dwScoketID);
	//遍历自己加入群的房间号 
	SendJoinGroup(dwUserID, dwScoketID);

	return true;
}

//发送自己加入的群
bool CAttemperEngineSink::SendJoinGroup(DWORD dwUserID, DWORD dwScoketID)
{
	//查找离线消息
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERJION, m_KindID, dwUserID);
	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];
	std::vector<DWORD> mMyJionGroupIDArray;
	mMyJionGroupIDArray.clear();

	if (dwDataLenArray.size() > 0)  //有缓存
	{
		for (int i = 0; i < dwDataLenArray.size(); i++)
		{
			if (dwDataLenArray.at(i) < SOCKET_TCP_PACKET)
			{
				if ((wSendSize + sizeof(GroupInfoEx)) > sizeof(cbDataBuffer))
				{
					m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_MYCREATEGROUP, cbDataBuffer, wSendSize);
					wSendSize = 0;
				}

				GroupInfoEx *mGroupStrcut = (GroupInfoEx*)strValueArray[i].c_str();
				mMyJionGroupIDArray.push_back(mGroupStrcut->mBaseGroupData.dwGroupID);
				snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, mGroupStrcut->mBaseGroupData.dwGroupID);
				int ListSizeCount = m_WhRedisServer.HashSize(RedisCmdLine);
				mGroupStrcut->dwGroupUserCnt = ListSizeCount > 0 ? ListSizeCount : 0;
				mGroupStrcut->dwGroupRoomCnt = m_GroupRoomManager.GetGroupArray(mGroupStrcut->mBaseGroupData.dwGroupID).size();
				CopyMemory(cbDataBuffer + wSendSize, mGroupStrcut, sizeof(GroupInfoEx));
				wSendSize += sizeof(GroupInfoEx);
			}
			else
			{
				CPushLog(ARRAY_V(dwScoketID, SYSFRIENDLOG), LOG_ERROR, _T("UserID:%d 获取自己群消息异常"), dwScoketID);
				ASSERT(0);
			}
		}

		if (wSendSize > 0 && dwScoketID != 0)
		{
			m_pITCPNetworkEngine->SendData(dwScoketID, MDM_GP_FRIENDSERVER, SUB_GP_MYCREATEGROUP, cbDataBuffer, wSendSize);
		}
	}

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);

	m_pITCPNetworkEngine->SendData(dwScoketID,MDM_GP_FRIENDSERVER, SUB_GP_MYGROUPLISTFINSH);

	CPushLog(ARRAY_V(dwUserID,SYSFRIENDLOG), LOG_DEBUG, _T("dwUserID:%d 加入的俱乐部数量:%d"), dwUserID, mMyJionGroupIDArray.size());
	 
	//遍历自己创建的群的所有房间号
	//SelectGroupID(mMyJionGroupIDArray, dwScoketID);
	 
	return true;
}

//删除特定群
bool CAttemperEngineSink::DeleteOnlyGroup(DWORD dwGroup, DWORD dwUserID, DWORD dwScoketID)
{
	//查找离线消息
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, dwGroup);
	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];

	if (dwDataLenArray.size() > 0)  //有缓存
	{
		for (int i = 0; i < dwDataLenArray.size(); i++)
		{
			GroupUserListInfo *pUserListInfo = (GroupUserListInfo*)strValueArray[i].c_str();
			tagBindParameter* pBindParameter = GetBindParameterToUser(pUserListInfo->dwUserID);
			if (pBindParameter != NULL)
			{   
				m_pITCPNetworkEngine->SendData(pBindParameter->dwSocketID,MDM_GP_FRIENDSERVER,SUB_GP_DELETEGROUPSUCCESS,&dwGroup,sizeof(dwGroup));
			
				CMD_GP_OPERATIONDESC OperationDesc;
				ZeroMemory(&OperationDesc, sizeof(OperationDesc));
				_sntprintf(OperationDesc.szDesc, CountArray(OperationDesc.szDesc), _T("群[%d]已解散,请退出亲友团"), dwGroup);
				//给群主发确认操作
				m_pITCPNetworkEngine->SendData(pBindParameter->dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPOWNERSUBMISSION, &OperationDesc, sizeof(OperationDesc));
			}

			char RedisCmdLineJion[100];
			ZeroMemory(RedisCmdLineJion,sizeof(RedisCmdLineJion));
			snprintf(RedisCmdLineJion, sizeof(RedisCmdLineJion), "%s:%d:%d", GROUPUSERJION, m_KindID, pUserListInfo->dwUserID);
			//遍历加入者 删除该群
			m_WhRedisServer.DeleteHashValueToScore(RedisCmdLineJion,dwGroup,dwGroup);
			ChangeUserAttribute(dwGroup, pUserListInfo->dwUserID, GroupType_EXIT, _T(""));
		}
	}

	CPushLog(ARRAY_V(dwUserID, SYSFRIENDLOG, dwGroup+CLUBLOG), LOG_DEBUG, _T("dwUserID:%d 删除俱乐部:%d"), dwUserID, dwGroup);

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);
	
	//删除群
	m_WhRedisServer.DelKey(RedisCmdLine);

	ZeroMemory(RedisCmdLine,sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, dwUserID);
	m_WhRedisServer.DeleteHashValueToScore(RedisCmdLine,dwGroup,dwGroup);

	//群号回收
	ZeroMemory(RedisCmdLine, sizeof(RedisCmdLine));
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPUUID, m_KindID);
	m_WhRedisServer.RpushList(RedisCmdLine, dwGroup);

	return true;
}

//遍历群成员
bool CAttemperEngineSink::OnforEachGroupUserList(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_FOREACHUSERLIST));
	if (wDataSize != sizeof(CMD_GP_FOREACHUSERLIST))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("审核操作 (CMD_GP_FOREACHUSERLIST) 目标:%d 实际:%d"), sizeof(CMD_GP_FOREACHUSERLIST), wDataSize);
		return false;
	}

	CMD_GP_FOREACHUSERLIST * pResult = (CMD_GP_FOREACHUSERLIST*)pData;
	CPushLog(ARRAY_V(dwSocketID), LOG_DEBUG, _T("遍历群成员 UserID:%d"), pResult->dwGroupID);

	//查找群成员
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, pResult->dwGroupID);

	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];
	std::vector<GroupUserListInfo*> mGroupUserListVt;

	//排序群主
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPIDTOOWNERID, m_KindID);
	DWORD GroupMainID = m_WhRedisServer.GetListIndexScore(RedisCmdLine, pResult->dwGroupID);
	ASSERT(GroupMainID != 0);

	for (int i=0;i<dwDataLenArray.size();i++)
	{
		GroupUserListInfo *mGroupUserList = (GroupUserListInfo *)strValueArray[i].c_str();
		if (mGroupUserList->dwUserID == GroupMainID)
		{
			mGroupUserListVt.insert(mGroupUserListVt.begin(),mGroupUserList);
		}
		else
		{
			mGroupUserListVt.push_back(mGroupUserList);
		}

		CPushLog(ARRAY_V(pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("遍历群成员 UserID:%d 昵称:%s"), mGroupUserList->dwUserID,mGroupUserList->szNickName);
	}


	if (dwDataLenArray.size() > 0)  //有缓存
	{
		for (int i = 0; i < mGroupUserListVt.size(); i++)
		{
			if (dwDataLenArray.at(i) < SOCKET_TCP_PACKET)
			{
				if ((wSendSize + dwDataLenArray[i]) > sizeof(cbDataBuffer))
				{
					m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_USERLISTRESULT, cbDataBuffer, wSendSize);
					wSendSize = 0;
				}

				CopyMemory(cbDataBuffer + wSendSize, mGroupUserListVt[i], dwDataLenArray[i]);
				wSendSize += dwDataLenArray[i];
			}
			else
			{
				CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("UserID:%d 获取离线消息异常"), pResult->dwGroupID);
				ASSERT(0);
			}
		}

		if (wSendSize > 0 && dwSocketID != 0)
		{
			m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_USERLISTRESULT, cbDataBuffer, wSendSize);
		}
	}

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);
	std::vector<GroupUserListInfo*>().swap(mGroupUserListVt);
	return true;
}

//修改群公告
bool CAttemperEngineSink::OnModifyGroupNotice(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	/*ASSERT(wDataSize == sizeof(CMD_GP_MODIFYNOTICE));
	if (wDataSize != sizeof(CMD_GP_MODIFYNOTICE))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("退出群消息结构大小不同 (CMD_GP_MODIFYNOTICE) 目标:%d 实际:%d"), sizeof(CMD_GP_MODIFYNOTICE), wDataSize);
		return false;
	}

	CMD_GP_MODIFYNOTICE * pNodifyGroup = (CMD_GP_MODIFYNOTICE*)pData;

	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPNOTICE, m_KindID, pNodifyGroup->dwGroupID);
	*/
 
	return true;
}


//修改群规则
bool CAttemperEngineSink::OnModifyGroupRule(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_ModifyGroupRule));
	if (wDataSize != sizeof(CMD_GP_ModifyGroupRule))
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("创建群消息结构大小不同 (CMD_GP_CREATEGROUP) 目标:%d 实际:%d"), sizeof(CMD_GP_ModifyGroupRule), wDataSize);
		return false;
	}

	CMD_GP_ModifyGroupRule * pNodifyGroup = (CMD_GP_ModifyGroupRule*)pData;
	ASSERT(pNodifyGroup->dwGroupID != 0);
	if (pNodifyGroup->dwGroupID == 0)
	{
		CPushLog(ARRAY_V(dwSocketID, SYSFRIENDLOG), LOG_ERROR, _T("修改群规则 群号为0"));
		return false;
	}

	tagBindParameter *BindParameter = GetBindParameterToUser(pNodifyGroup->mCreateInfo.dwUserID);
	if (BindParameter != NULL)
	{
		////检查UserID 创建次数
		char RedisCmdLine[100];
		snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSEROWNER, m_KindID, pNodifyGroup->mCreateInfo.dwUserID);
		int CreateCnt = m_WhRedisServer.DeleteHashValueToScore(RedisCmdLine, pNodifyGroup->dwGroupID, pNodifyGroup->dwGroupID);
		
		 CMD_GP_CREATEGROUP CmdCreateGroup;
		ZeroMemory(&CmdCreateGroup,sizeof(CmdCreateGroup));
		CopyMemory(&CmdCreateGroup, &(pNodifyGroup->mCreateInfo) ,sizeof(CmdCreateGroup));
		SerializationGroupInfoToRedis(&CmdCreateGroup, pNodifyGroup->dwGroupID, BindParameter->pUserInfo, GroupType_Create, 0);
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_MODIYGROUPRESULT, pData, wDataSize);
	}
	else
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("用戶不在线 修改群规则 Useid:%d",pNodifyGroup->dwUserID));
		ASSERT(0);
		OnSendPublicMessage(dwSocketID, 0, _T("修改群规则失败"));
	}

	return true;
}

//检查或者生成群号
bool CAttemperEngineSink::CheckCreateGroupID()
{

	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPUUID, m_KindID);

	int lastID = m_WhRedisServer.ListSize(RedisCmdLine);
	if (lastID == 0)
	{
		std::vector<std::string> mStrIDAry;
		mStrIDAry.clear();

		for (int i = 100000; i < 999999; i++)
		{
			mStrIDAry.push_back(std::to_string(i));
		}

		std::random_shuffle(mStrIDAry.begin(), mStrIDAry.end());
		m_WhRedisServer.LpushList(RedisCmdLine, mStrIDAry);
	}
	else
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("当前俱乐部剩余群号:%d KindID:%d"), lastID,m_KindID);
	}
	return true;
}

int CAttemperEngineSink::GetGroupUUID()
{
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d", GROUPUUID, m_KindID); // Group:GroupUUID

	std::string GetUUID = m_WhRedisServer.GetListFristValue(RedisCmdLine);
	if (GetUUID.size() <= 0)
	{
		ASSERT(0);
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("uuid已经用完 或者出现异常"));
		CTraceService::TraceString(_T("uuid已经用完 或者出现异常"), TraceLevel_Exception);
	}

	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("得到群号:%d"), GetUUID);
	return std::stoi(GetUUID);
}

void CAttemperEngineSink::GetRedisToRoomList()
{
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:*", GROUPLISTACTIVE, m_KindID);
	m_WhRedisServer.GetVagueBufferData(RedisCmdLine,strValueArray,dwDataLenArray);

	//查找群数据
	for (int i = 0; i < dwDataLenArray.size(); i++)
	{
		std::vector<std::string> strGroupInfoArray;
		std::vector<int> dwGroupLenArray;

		char  RedisName[100];
		strcpy(RedisName, strValueArray[i].c_str());
		m_WhRedisServer.GetZddArrayBufferData(RedisName, "0", "-1", strGroupInfoArray, dwGroupLenArray);
			
		for (int k=0;k<dwGroupLenArray.size();k++)
		{
			OnGroupCreateRoom((void*)(strGroupInfoArray[k].c_str()) ,dwGroupLenArray[k],0);
		}

		strGroupInfoArray.clear();
		dwGroupLenArray.clear();
		std::vector<std::string>().swap(strGroupInfoArray);
		std::vector<int>().swap(dwGroupLenArray);
	}

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);

}

//亲友团日志流水
bool CAttemperEngineSink::RecordGroupLog(DWORD dwGroupID, DWORD dwsUserID, TCHAR szDesc[128],DWORD KindID /* = 100 */)
{
	DBR_GP_GROUPLOG  CmdGroupLog;
	ZeroMemory(&CmdGroupLog, sizeof(CmdGroupLog));
	CmdGroupLog.dwGroupID = dwGroupID;
	CmdGroupLog.dwKindID = m_KindID;
	CmdGroupLog.dwUserID = dwsUserID;
	lstrcpyn(CmdGroupLog.szDescLog,szDesc,CountArray(CmdGroupLog.szDescLog));
	m_pIDataBaseEngine->PostDataBaseRequest(DBR_GP_GROUP_LOG, 0, &CmdGroupLog, sizeof(CmdGroupLog));
	return true;
}

//改变用户属性
bool CAttemperEngineSink::ChangeUserAttribute(DWORD dwGroupID, DWORD dwsUserID,BYTE OperationType, TCHAR szGroupName[32])
{
	DBR_GP_ChangeUserAttribute  CmdChangeUserAttribute;
	ZeroMemory(&CmdChangeUserAttribute,sizeof(CmdChangeUserAttribute));
	CmdChangeUserAttribute.dwUserID = dwsUserID;
	CmdChangeUserAttribute.dwGroupID = dwGroupID;
	CmdChangeUserAttribute.dwType = OperationType;
	lstrcpyn(CmdChangeUserAttribute.szGroupName,szGroupName,CountArray(szGroupName));
	m_pIDataBaseEngine->PostDataBaseRequest(DBR_GP_GROUP_CHANGEATTRIBUTE, 0, &CmdChangeUserAttribute, sizeof(CmdChangeUserAttribute));
	return true;
}

//房间创建
bool CAttemperEngineSink::OnGroupCreateRoom(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	//插入房间
	m_GroupRoomManager.InsertGroupCreateRoom(pData,wDataSize);

	ASSERT(wDataSize == sizeof(CMD_GP_FRIEND_CREATETABLE));
	if (wDataSize != sizeof(CMD_GP_FRIEND_CREATETABLE))
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("审核操作 (CMD_GP_FOREACHUSERLIST) 目标:%d 实际:%d"), sizeof(CMD_GP_FRIEND_CREATETABLE), wDataSize);
		return false;
	}
	CMD_GP_FRIEND_CREATETABLE * pResult = (CMD_GP_FRIEND_CREATETABLE*)pData;

	//CPushLog(ARRAY_V(dwSocketID,pResult->dwGroupID + CLUBLOG),LOG_DEBUG,_T("俱乐部有新房间创建 房间号:%d"),pResult->dwRoomID);

	if (dwSocketID != 0)
	{
		SendDataToGroup(pResult->dwGroupID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPCREATETABLE, pData, wDataSize, dwSocketID);
	}
	//广播群消息
	CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_DEBUG, _T("收到房间创建,执行完成"));

	return true;
}

//房间修改
bool CAttemperEngineSink::OnGroupModityRoomStatus(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_FRIEND_TABLEPLAYSTATUS));
	if (wDataSize != sizeof(CMD_GP_FRIEND_TABLEPLAYSTATUS))
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("俱乐部修改房间 (CMD_GP_FOREACHUSERLIST) 目标:%d 实际:%d"), sizeof(CMD_GP_FRIEND_TABLEPLAYSTATUS), wDataSize);
		return false;
	}
	 
	CMD_GP_FRIEND_TABLEPLAYSTATUS *pResult = (CMD_GP_FRIEND_TABLEPLAYSTATUS*)pData;
	m_GroupRoomManager.ModityGroupRoomStatus(pResult->dwGroupID, pResult->dwRoomID, pResult->cbPlayCnt);
	//广播群消息
	SendDataToGroup(pResult->dwGroupID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPMODITYTABLE, pData, wDataSize, dwSocketID);
	return true;
}

//删除房间
bool CAttemperEngineSink::OnGroupDeleteRoom(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_FRIEND_DELETEROOM));
	if (wDataSize != sizeof(CMD_GP_FRIEND_DELETEROOM))
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("俱乐部删除房间 (CMD_GP_FOREACHUSERLIST) 目标:%d 实际:%d"), sizeof(CMD_GP_FRIEND_DELETEROOM), wDataSize);
		return false;
	}
	CMD_GP_FRIEND_DELETEROOM * pResult = (CMD_GP_FRIEND_DELETEROOM*)pData;
	m_GroupRoomManager.DeleteGroupRoom(pResult->dwGroupID,pResult->dwRoomID);
	//广播群消息
	SendDataToGroup(pResult->dwGroupID, MDM_GP_FRIENDSERVER,SUB_GP_GROUPDELETETABLE, pData, wDataSize, dwSocketID);
	return true;
}

//发送俱乐部消息
bool CAttemperEngineSink::SendDataToGroup(DWORD GropuID, WORD wMainCmdID, WORD wSubCmdID,VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	//广播群  
	std::vector<DWORD> mUserList;
	GetGroupUserList(GropuID, mUserList);

	if (mUserList.size() > 0)
	{
		for (int i = 0; i < mUserList.size(); i++)
		{
			tagBindParameter* mBindParameter = GetBindParameterToUser(mUserList.at(i));
			if (mBindParameter != NULL)
			{
				m_pITCPNetworkEngine->SendData(mBindParameter->dwSocketID,wMainCmdID, wSubCmdID, pData, wDataSize);
			}
		}
	}

	return true;
}

//查找群成员
bool CAttemperEngineSink::GetGroupUserList(DWORD dwGroupID, std::vector<DWORD> & mResultArray)
{
	mResultArray.clear();

	//查找群成员
	std::vector<std::string> strValueArray;
	std::vector<int> dwDataLenArray;
	char RedisCmdLine[100];
	snprintf(RedisCmdLine, sizeof(RedisCmdLine), "%s:%d:%d", GROUPUSERINFOLIST, m_KindID, dwGroupID);

	m_WhRedisServer.GetZddArrayBufferData(RedisCmdLine, "0", "-1", strValueArray, dwDataLenArray);

	for (int i = 0; i < dwDataLenArray.size(); i++)
	{
		GroupUserListInfo *mGroupUserList = (GroupUserListInfo *)strValueArray[i].c_str();
		if (mGroupUserList != NULL)
		{
			mResultArray.push_back(mGroupUserList->dwUserID);
		}
	}

	dwDataLenArray.clear();
	strValueArray.clear();
	std::vector<std::string>().swap(strValueArray);
	std::vector<int>().swap(dwDataLenArray);

	CPushLog(ARRAY_V(SYSFRIENDLOG),LOG_DEBUG,_T("群ID:%d 群成员数量:%d"),dwGroupID,mResultArray.size());
	return true;
}

//自己创建&自家加入的 俱乐部 房间总信息
bool CAttemperEngineSink::SelectGroupID(std::vector<DWORD> mSelectGroupID, DWORD dwSocketID)
{
	for (int i = 0; i < mSelectGroupID.size(); i++)
	{
		std::vector<GroupCreateRoomInfo> mGroupArray = m_GroupRoomManager.GetGroupArray(mSelectGroupID.at(i));

		WORD wSendSize = 0;
		BYTE cbDataBuffer[SOCKET_TCP_PACKET];

		GroupCreateRoomInfo CreateRoomInfo;
		ZeroMemory(&CreateRoomInfo, sizeof(CreateRoomInfo));

		for (int j = 0; j < mGroupArray.size(); j++)
		{
			//发送数据
			if ((wSendSize + sizeof(GroupCreateRoomInfo)) > sizeof(cbDataBuffer))
			{
				m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPALLINFO, cbDataBuffer, wSendSize);
				wSendSize = 0;
			}

			CreateRoomInfo = mGroupArray.at(j);
			//拷贝数据
			CopyMemory(cbDataBuffer + wSendSize, &CreateRoomInfo, sizeof(CreateRoomInfo));
			wSendSize += sizeof(GroupCreateRoomInfo);
		}

		//发送剩余
		if (wSendSize > 0)
		{
			m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPALLINFO, cbDataBuffer, wSendSize);
		}
	}

	return true;
}

//查询群房间数
bool CAttemperEngineSink::OnGetGroupRoomInfo(VOID * pData, WORD wDataSize, DWORD dwSocketID)
{
	ASSERT(wDataSize == sizeof(CMD_GP_GetGroupRoomInfo));
	if (wDataSize != sizeof(CMD_GP_GetGroupRoomInfo))
	{
		CPushLog(ARRAY_V(SYSFRIENDLOG), LOG_ERROR, _T("俱乐部房间查询 (CMD_GP_GetGroupRoomInfo) 目标:%d 实际:%d"), sizeof(CMD_GP_GetGroupRoomInfo), wDataSize);
		return false;
	}

	CMD_GP_GetGroupRoomInfo * pResult = (CMD_GP_GetGroupRoomInfo*)pData;
	std::vector<GroupCreateRoomInfo> mGroupArray = m_GroupRoomManager.GetGroupArray(pResult->dwGroupID);

	CPushLog(ARRAY_V(SYSFRIENDLOG,pResult->dwGroupID + CLUBLOG), LOG_DEBUG, _T("查询群:%d 房间数量为:%d"),pResult->dwGroupID,mGroupArray.size());

	WORD wSendSize = 0;
	BYTE cbDataBuffer[SOCKET_TCP_PACKET];

	GroupCreateRoomInfo CreateRoomInfo;
	ZeroMemory(&CreateRoomInfo, sizeof(CreateRoomInfo));

	for (int j = 0; j < mGroupArray.size(); j++)
	{
		//发送数据
		if ((wSendSize + sizeof(GroupCreateRoomInfo)) > sizeof(cbDataBuffer))
		{
			m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPALLINFO, cbDataBuffer, wSendSize);
			wSendSize = 0;
		}

		CreateRoomInfo = mGroupArray.at(j);
		//拷贝数据
		CopyMemory(cbDataBuffer + wSendSize, &CreateRoomInfo, sizeof(CreateRoomInfo));
		wSendSize += sizeof(GroupCreateRoomInfo);
	}

	//发送剩余
	if (wSendSize > 0)
	{
		m_pITCPNetworkEngine->SendData(dwSocketID, MDM_GP_FRIENDSERVER, SUB_GP_GROUPALLINFO, cbDataBuffer, wSendSize);
	}

	return true;
}
